from PySide6.QtCore import Qt, QDateTime
from PySide6.QtWidgets import QHeaderView, QTableWidgetItem, QMessageBox
from PySide6.QtGui import QIcon

from Devices.Device import Device, ChiotDevice
from Devices.DeviceWindow import DeviceWindow
from Devices.Andlink.AndlinkParser import AndlinkParser
from Devices.Andlink.Forms.SendCoAPWindow import SendCoAPWindow
from Communicate.CoapClient import CoapClient
from Devices.Andlink.DeviceAndlink import DeviceAndlink

from Devices.Andlink.Forms.AndlinkWindow_UI import Ui_FormAndlinkWindow

class AndlinkWindow(DeviceWindow):
    def __init__(self, supportDevice, parent = None):
        super().__init__(supportDevice, parent)

        self.__ui = Ui_FormAndlinkWindow()
        self.__ui.setupUi(self)
        self.SetupUi(self.__ui)
        
        self.__SendCoAPWindow = SendCoAPWindow()
        self.__SupportTcp = True if isinstance(supportDevice, Device.SupportChiotDevice) else False
        self.__AndlinkParser = AndlinkParser()
        self.__DeviceFullStatus = DeviceAndlink.DeviceFullStatus()
        self.__CoapClient = CoapClient()
        self.__LogUrl = ""
        self.__OtaStarted = False

        self.__LogUrl = self.__ui.lineEdit_LogUrl.text()
        self._OtaUrl = self.__ui.lineEdit_downloadUrl.text()

        self.__ui.pushButton_Log.setVisible(self.__SupportTcp)
        self.__ui.pushButton_SendCmd.setVisible(self.__SupportTcp)

        self.__ui.tabWidget.setCurrentIndex(0)
        self.__ui.tableWidget_chips.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)

        self.__ui.progressBar_Ota.setVisible(False)

        self.__SendCoAPWindow.SetDeviceName(self._SupportDevice.deviceDisplayName)

        self.__CoapClient.CoapFinished.connect(self.on_CoapFinished)
        self.__CoapClient.CoapFailed.connect(self.on_CoapFailed)

        self.__SendCoAPWindow.SendCoAPTriggerd.connect(self.PostIPTriggerd)

        self.__ui.pushButton_Sync.clicked.connect(self.event_pushButton_Sync_clicked)
        self.__ui.pushButton_SendCoAP.clicked.connect(self.event_pushButton_SendCoAP_clicked)
        self.__ui.pushButton_Unbind.clicked.connect(self.event_pushButton_Unbind_clicked)
        self.__ui.pushButton_Kickout.clicked.connect(self.event_pushButton_Kickout_clicked)
        self.__ui.pushButton_SetWiFi.clicked.connect(self.event_pushButton_SetWiFi_clicked)
        self.__ui.pushButton_OpenLog.clicked.connect(self.event_pushButton_OpenLog_clicked)
        self.__ui.pushButton_UploadLog.clicked.connect(self.event_pushButton_UploadLog_clicked)
        self.__ui.pushButton_OTA.clicked.connect(self.event_pushButton_OTA_clicked)
        self.__ui.pushButton_Selfdetect.clicked.connect(self.event_pushButton_Selfdetect_clicked)
        self.__ui.pushButton_Reset.clicked.connect(self.event_pushButton_Reset_clicked)
        self.__ui.pushButton_ClearWiFi.clicked.connect(self.event_pushButton_ClearWiFi_clicked)
        self.__ui.pushButton_ClearLog.clicked.connect(self.event_pushButton_ClearLog_clicked)
        self.__ui.pushButton_Reboot.clicked.connect(self.event_pushButton_Reboot_clicked)

    def GetDeviceFullStatus(self):
        return self.__DeviceFullStatus

    def CoapFinished(self, url, coapMsg):
        return False

    def SetAddtionTab(self, tabWidget):
        for i in range(tabWidget.count()):
            widget = tabWidget.widget(i)
            txt = tabWidget.tabText(i)
            self.__ui.tabWidget.addTab(widget, txt)

    def Connect(self, cmdPort, logPort):
        if self.__SupportTcp:
            super().Connect(cmdPort, logPort)
        else:
            self.setWindowTitle(self._OriginalTitle + ":" + self._DeviceIP)

        self.__CoapClient.SetIP(self._DeviceIP)
        self.__CoapClient.Post(DeviceAndlink.UrlDeviceInfo, "{}")
        self.SendCommandText("{}")

        self.__SendCoAPWindow.SetDeviceIP(self._DeviceIP)

        self.__ui.lineEdit_LogUrl.setText(self.__LogUrl % (self._HttpServerWindow.GetIP(), self._HttpServerWindow.GetPort()))
        self.__ui.lineEdit_downloadUrl.setText(self._OtaUrl % (self._HttpServerWindow.GetIP(), self._HttpServerWindow.GetPort(), self._SupportDevice.deviceBinName))

    def ReConnect(self):
        if self.__SupportTcp:
            super().ReConnect()

        self.__CoapClient.Post(DeviceAndlink.UrlDeviceInfo, "{}")
        self.SendCommandText("{}")

    def Connected(self, ip, port):
        pass

    def CmdDateReceived(self, data):
        ret, eventType, dataObj = AndlinkParser.ParseEvent(data)
        if ret:
            if self.__OtaStarted and ("File" == eventType or "OTA" == eventType):
                respCode = int(dataObj["respCode"]) if ("respCode" in dataObj) else -1
                respCont = int(dataObj["respCont"]) if ("respCont" in dataObj) else -1
                if 2002 == respCode:
                    self.__ui.progressBar_Ota.setVisible(100 != respCont)
                    self.__ui.progressBar_Ota.setValue(respCont)
                    if 100 == respCont:
                        self.__OtaStarted = False
                        self.ShowMessageBox("设备升级", "设备升级完成,等待重启...")

    def Post(self, url, content):
        self.__CoapClient.Post(url, content)

    def PostIPTriggerd(self, ip, url, content):
        self.__CoapClient.SetIP(ip)
        self.__CoapClient.Post(url, content)

    def event_pushButton_Sync_clicked(self):
        self.__CoapClient.Post(DeviceAndlink.UrlDeviceInfo, "{}")
        self.SendCommandText("{}")

    def event_pushButton_SendCoAP_clicked(self):
        self.__SendCoAPWindow.showNormal()
        self.__SendCoAPWindow.activateWindow()

    def event_pushButton_Unbind_clicked(self):
        payload = self.__AndlinkParser.PackEmpty("Unbind")
        self.__CoapClient.Post(DeviceAndlink.UrlUnbind, payload)

    def event_pushButton_Kickout_clicked(self):
        payload = self.__AndlinkParser.PackEmpty("")
        self.__CoapClient.Post(DeviceAndlink.UrlKickout, payload)

    def event_pushButton_SetWiFi_clicked(self):
        payload = self.__AndlinkParser.PackNetinfo(self.__ui.lineEdit_SSID.text(), self.__ui.lineEdit_Password.text())
        self.__CoapClient.Post(DeviceAndlink.UrlNetinfo, payload)

    def event_pushButton_OpenLog_clicked(self):
        payload = self.__AndlinkParser.PackOpenLog(self.__ui.comboBox_Loglvl.currentIndex(), int(self.__ui.lineEdit_LogTime.text()), self.__ui.lineEdit_LogUrl.text())
        self.__CoapClient.Post(DeviceAndlink.UrlLog, payload)

    def event_pushButton_UploadLog_clicked(self):
        payload = self.__AndlinkParser.PackUploadLog(self.__ui.lineEdit_LogUrl.text())
        self.__CoapClient.Post(DeviceAndlink.UrlFile, payload)

    def event_pushButton_OTA_clicked(self):
        if (0 == self.__ui.comboBox_OtaInterface.currentIndex()):
            payload = self.__AndlinkParser.PackFileDownload(self.__ui.lineEdit_downloadUrl.text(), self.__ui.comboBox_OtaType.currentIndex())
        else:
            payload = self.__AndlinkParser.PackOTA(self.__ui.lineEdit_downloadUrl.text(), self.__DeviceFullStatus.deviceType)
        
        self.__CoapClient.Post(DeviceAndlink.UrlFile, payload)
        self.__OtaStarted = True

    def event_pushButton_Selfdetect_clicked(self):
        payload = self.__AndlinkParser.PackEmpty("SelfDetect")
        self.__CoapClient.Post(DeviceAndlink.UrlSelfdetect, payload)

    def event_pushButton_Reset_clicked(self):
        payload = AndlinkParser.PackInnerCommand(0)
        self.__CoapClient.Post(DeviceAndlink.UrlInnerCommand, payload)

    def event_pushButton_ClearWiFi_clicked(self):
        payload = AndlinkParser.PackInnerCommand(1)
        self.__CoapClient.Post(DeviceAndlink.UrlInnerCommand, payload)

    def event_pushButton_ClearLog_clicked(self):
        self.__CoapClient.SetTimeout(15)
        payload = AndlinkParser.PackInnerCommand(2)
        self.__CoapClient.Post(DeviceAndlink.UrlInnerCommand, payload)
        
    def event_pushButton_Reboot_clicked(self):
        payload = AndlinkParser.PackInnerCommand(3)
        self.__CoapClient.Post(DeviceAndlink.UrlInnerCommand, payload)

    def on_CoapFinished(self, success, url, sendMsg, coapMsg):
        self.__CoapClient.SetTimeout(2)
        self._MessagesWindow.AddSentMsg(url + ":" + sendMsg)

        if success:
            self._MessagesWindow.AddReceivedMsg(url + ":" + coapMsg)

            if DeviceAndlink.UrlDeviceInfo in url:
                if AndlinkParser.ParseFullStatus(coapMsg, self.__DeviceFullStatus):
                    self.__AndlinkParser.SetDeviceID(self.__DeviceFullStatus.deviceId)
                    #基本信息
                    self.__ui.label_deviceId.setText(self.__DeviceFullStatus.deviceId)
                    self.__ui.label_deviceMac.setText(self.__DeviceFullStatus.deviceMac)
                    self.__ui.label_deviceType.setText(self.__DeviceFullStatus.deviceType)
                    self.__ui.label_deviceToken.setText(self.__DeviceFullStatus.deviceToken)
                    self.__ui.label_productToken.setText(self.__DeviceFullStatus.productToken)
                    self.__ui.label_andlinkToken.setText(self.__DeviceFullStatus.andlinkToken)
                    self.__ui.label_firmwareVersion.setText(self.__DeviceFullStatus.firmwareVersion)
                    self.__ui.label_softwareVersion.setText(self.__DeviceFullStatus.softwareVersion)
                    self.__ui.label_protocolVersion.setText(self.__DeviceFullStatus.protocolVersion)

                    #扩展信息
                    self.__ui.label_cmei.setText(self.__DeviceFullStatus.deviceExtInfo.cmei)
                    self.__ui.label_sn.setText(self.__DeviceFullStatus.deviceExtInfo.sn)
                    self.__ui.label_OS.setText(self.__DeviceFullStatus.deviceExtInfo.OS)

                    if 0 == self.__DeviceFullStatus.deviceExtInfo.authMode:
                        self.__ui.label_authMode.setText("类型认证")
                        self.__ui.label_authMode.setStyleSheet("color:Green")
                    elif 1 == self.__DeviceFullStatus.deviceExtInfo.authMode:
                        self.__ui.label_authMode.setText("设备认证")
                        self.__ui.label_authMode.setStyleSheet("color:Blue")
                    else:
                        self.__ui.label_authMode.setText("未知")
                        self.__ui.label_authMode.setStyleSheet("color:Red")

                    self.__ui.label_authId.setText(self.__DeviceFullStatus.deviceExtInfo.authId)
                    self.__ui.label_cmei.setText(self.__DeviceFullStatus.deviceExtInfo.cmei)
                    self.__ui.label_reserve.setText(self.__DeviceFullStatus.deviceExtInfo.reserve)

                    self.__ui.tableWidget_chips.setRowCount(0)
                    for i in range(len(self.__DeviceFullStatus.deviceExtInfo.chips)):
                        self.__ui.tableWidget_chips.insertRow(i)

                        item = None
                        self.__ui.tableWidget_chips.setItem(i, 0, item := QTableWidgetItem(self.__DeviceFullStatus.deviceExtInfo.chips[i].type))
                        item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

                        self.__ui.tableWidget_chips.setItem(i, 1, item := QTableWidgetItem(self.__DeviceFullStatus.deviceExtInfo.chips[i].factory))
                        item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

                        self.__ui.tableWidget_chips.setItem(i, 2, item := QTableWidgetItem(self.__DeviceFullStatus.deviceExtInfo.chips[i].model))
                        item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

                    self.__ui.label_cpuModel.setText(self.__DeviceFullStatus.deviceExtInfo.cpuModel)
                    self.__ui.label_romStorageSize.setText(self.__DeviceFullStatus.deviceExtInfo.romStorageSize)
                    self.__ui.label_ramStorageSize.setText(self.__DeviceFullStatus.deviceExtInfo.ramStorageSize)
                    self.__ui.label_networkType.setText(self.__DeviceFullStatus.deviceExtInfo.networkType)
                    self.__ui.label_deviceVendor.setText(self.__DeviceFullStatus.deviceExtInfo.deviceVendor)
                    self.__ui.label_deviceBrand.setText(self.__DeviceFullStatus.deviceExtInfo.deviceBrand)
                    self.__ui.label_deviceModel.setText(self.__DeviceFullStatus.deviceExtInfo.deviceModel)
                    self.__ui.label_wlanMac.setText(self.__DeviceFullStatus.deviceExtInfo.wlanMac)
                    self.__ui.label_bluetoothMacAddress.setText(self.__DeviceFullStatus.deviceExtInfo.bluetoothMacAddress)
                    self.__ui.label_powerSupplyMode.setText(self.__DeviceFullStatus.deviceExtInfo.powerSupplyMode)
                    self.__ui.label_wifiRssi.setText(self.__DeviceFullStatus.deviceExtInfo.wifiRssi + "dBm")
                    self.__ui.label_manuDate.setText(self.__DeviceFullStatus.deviceExtInfo.manuDate)

                    #辅助信息
                    if 1 == self.__DeviceFullStatus.bindStatus:
                        self.__ui.label_bindStatus.setText("已绑定")
                        self.__ui.label_bindStatus.setStyleSheet("color:Green")
                    else:
                        self.__ui.label_bindStatus.setText("未绑定")
                        self.__ui.label_bindStatus.setStyleSheet("color:Red")

                    if 1 == self.__DeviceFullStatus.bootstrapStatus:
                        self.__ui.label_bootstrapStatus.setText("已注册")
                        self.__ui.label_bootstrapStatus.setStyleSheet("color:Green")
                    else:
                        self.__ui.label_bootstrapStatus.setText("未注册")
                        self.__ui.label_bootstrapStatus.setStyleSheet("color:Red")

                    if 1 == self.__DeviceFullStatus.bootStatus:
                        self.__ui.label_bootStatus.setText("已上线")
                        self.__ui.label_bootStatus.setStyleSheet("color:Green")
                    else:
                        self.__ui.label_bootStatus.setText("未上线")
                        self.__ui.label_bootStatus.setStyleSheet("color:Red")

                    if 1 == self.__DeviceFullStatus.offlineStatus:
                        self.__ui.label_offlineStatus.setText("已离线")
                        self.__ui.label_offlineStatus.setStyleSheet("color:Red")
                    else:
                        self.__ui.label_offlineStatus.setText("未离线")
                        self.__ui.label_offlineStatus.setStyleSheet("color:Green")

                    self.__ui.label_bootstrapLastFailTime.setText(str(self.__DeviceFullStatus.bootstrapLastFailTime))
                    self.__ui.label_bootstrapFailWaitTime.setText(str(self.__DeviceFullStatus.bootstrapFailWaitTime))
                    self.__ui.label_bootLastFailTime.setText(str(self.__DeviceFullStatus.bootLastFailTime))
                    self.__ui.label_bootFailWaitTime.setText(str(self.__DeviceFullStatus.bootFailWaitTime))

                    self.__ui.label_bootLastSuccessTime.setText(QDateTime.fromMSecsSinceEpoch(self.__DeviceFullStatus.bootLastSuccessTime).toString("yyyy-MM-dd HH:mm:ss"))
                    self.__ui.label_lastDmReportTime.setText(QDateTime.fromMSecsSinceEpoch(self.__DeviceFullStatus.lastDmReportTime).toString("yyyy-MM-dd HH:mm:ss"))
                    self.__ui.label_lastCheckUpgradeTime.setText(QDateTime.fromMSecsSinceEpoch(self.__DeviceFullStatus.lastCheckUpgradeTime).toString("yyyy-MM-dd HH:mm:ss"))

                    self.__ui.label_innerInfo.setText(self.__DeviceFullStatus.innerInfo)

                    self.ShowMessageBox("设备信息同步", "信息同步成功!")
                else:
                    self.ShowMessageBox("设备信息同步", "信息同步失败!", QMessageBox.Critical)
            elif DeviceAndlink.UrlControl in url:
                self.ShowMessageBox("设备控制", "设备控制指令发送成功!")
            elif DeviceAndlink.UrlUnbind in url:
                self.ShowMessageBox("设备解绑", "设备解绑指令发送成功!")
            elif DeviceAndlink.UrlKickout in url:
                self.ShowMessageBox("设备断开连接", "设备断开连接指令发送成功!")
            elif DeviceAndlink.UrlFile in url:
                self.ShowMessageBox("设备文件操作", "设备文件操作指令发送成功!")
            elif DeviceAndlink.UrlNetinfo in url:
                self.ShowMessageBox("设备Wi-Fi配置", "设备Wi-Fi配置指令发送成功!")
            elif DeviceAndlink.UrlLog in url:
                self.ShowMessageBox("设备日志配置", "设备日志配置指令发送成功!")
            elif DeviceAndlink.UrlSelfdetect in url:
                selfdetectInfo = DeviceAndlink.SelfdetectInfo()
                if AndlinkParser.ParseSelfdetect(coapMsg, selfdetectInfo):
                    self.__ui.label_cpuRate.setText(str(selfdetectInfo.cpuRate) + "%")
                    self.__ui.label_ramRate.setText(str(selfdetectInfo.ramRate) + "%")
                    self.__ui.label_upLinkType.setText(selfdetectInfo.upLinkType)

                    if 1 == selfdetectInfo.andlinkStatus:
                        self.__ui.label_andlinkStatus.setText("正常")
                        self.__ui.label_andlinkStatus.setStyleSheet("font:12pt; color:Green")
                    else:
                        self.__ui.label_andlinkStatus.setText("断链")
                        self.__ui.label_andlinkStatus.setStyleSheet("font:12pt; color:Red")

                    self.__ui.label_lastUpTime.setText(QDateTime.fromSecsSinceEpoch(selfdetectInfo.lastUpTime).toString("yyyy-MM-dd HH:mm:ss"))
                    self.__ui.label_lastConnTime.setText(QDateTime.fromSecsSinceEpoch(selfdetectInfo.lastConnTime).toString("yyyy-MM-dd HH:mm:ss"))

                    self.ShowMessageBox("设备自检", "设备自检完成!")
                else:
                    self.ShowMessageBox("设备自检", "设备自检信息解析失败!", QMessageBox.Critical)
            elif DeviceAndlink.UrlInnerCommand in url:
                self.ShowMessageBox("设备调试", "设备调试指令发送成功!")

            self.CoapFinished(url, coapMsg)

    def on_CoapFailed(self, errorMsg):
        self.__CoapClient.SetTimeout(2)
        self.ShowMessageBox("设备通信", "设备通信失败：" + errorMsg, QMessageBox.Critical)

    def HttpStarted(self):
        self.__ui.lineEdit_LogUrl.setText(self.__LogUrl % (self._HttpServerWindow.GetIP(), self._HttpServerWindow.GetPort()))
        self.__ui.lineEdit_downloadUrl.setText(self._OtaUrl % (self._HttpServerWindow.GetIP(), self._HttpServerWindow.GetPort(), self._SupportDevice.deviceBinName))

    def HttpStopped(self):
        pass
